﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using TabbedTemplate.Services;
using Xamarin.Forms.Extended;

namespace TabbedTemplate.ViewModels
{
    public class
        CityLocationsViewModel : ViewModelBase, INotifyPropertyChanged
    {
        // ******** 绑定属性
        private InfiniteScrollCollection<string> _cities;

        public InfiniteScrollCollection<string> Cities
        {
            get => _cities;
            set => Set(nameof(Cities), ref _cities, value);
        }

        private string _status;

        public string Status
        {
            get => _status;
            set => Set(nameof(Status), ref _status, value);
        }

        public string His1 { get; set; }
        public string His2 { get; set; }
        public string Input { get; set; }
        public string CurrentCity { get; set; }

        public bool CanLoadMore;

        public bool NewQuery;

        public int PageNum { get; set; }

        // ******** 依赖注入
        private readonly IPunchNavigationService _punchNavigationService;
        private readonly ICityLocationsService _cityLocationsService;
        private readonly IPreferenceStorage _preferenceStorage;

        public CityLocationsViewModel(
            IPunchNavigationService punchNavigationService,
            ICityLocationsService cityLocationsService,
            IPreferenceStorage preferenceStorage)
        {
            _punchNavigationService = punchNavigationService;
            _cityLocationsService = cityLocationsService;
            _preferenceStorage = preferenceStorage;
            Cities = new InfiniteScrollCollection<string>();
            His1 = _preferenceStorage.Get("His1", "北京市");
            His2 = _preferenceStorage.Get("His2", "重庆市");
        }


        public new event PropertyChangedEventHandler PropertyChanged;

        protected virtual void NotifyPropertyChanged(
            [CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this,
                new PropertyChangedEventArgs(propertyName));
        }


        // ******** 绑定命令
        private RelayCommand _pageAppearingCommand;

        public RelayCommand PageAppearingCommand =>
            _pageAppearingCommand ??= new RelayCommand(async () =>
                await PageAppearingCommandFunction());

        public async Task PageAppearingCommandFunction()
        {
            await _cityLocationsService.CloseAsync();
            CurrentCity = _preferenceStorage.Get("CurrentCity", "北京市");
            His1 = _preferenceStorage.Get("His1", "上海市");
            His2 = _preferenceStorage.Get("His2", "重庆市");
            NotifyPropertyChanged($"CurrentCity");
            NotifyPropertyChanged($"His1");
            NotifyPropertyChanged($"His2");
            Status = IndexPageViewModel.Loading;

            if (!_cityLocationsService.CityListInitilized())
            {
                await _cityLocationsService.InitializeCityListAsync();
            }

            await _cityLocationsService.InitializeCityListAsync();

            Input = "";
            NotifyPropertyChanged($"Input");
            PageNum = 0;
            Cities.Clear();
            Cities.OnCanLoadMore = () => CanLoadMore;
            Cities.OnLoadMore = async () =>
            {
                var cities =
                    (await _cityLocationsService.GetCityListAsync(Cities.Count,
                        StoreService.PageSize)).Select(p => p.CityName)
                    .ToList();

                if (cities.Count < StoreService.PageSize)
                {
                    CanLoadMore = false;
                    Status = IndexPageViewModel.NoMoreResult;
                }
                else
                {
                    Status = "";
                }

                if (Cities.Count == 0 && cities.Count == 0)
                {
                    Status = IndexPageViewModel.NoResult;
                }

                NotifyPropertyChanged($"Status");
                return cities;
            };
            CanLoadMore = true;
            await Cities.LoadMoreAsync();
            NewQuery = false;
        }

        private RelayCommand<string> _cityTappedCommand;

        public RelayCommand<string> CityTappedCommand =>
            _cityTappedCommand ??= new RelayCommand<string>(async cityName =>
                await CityTappedCommandFunction(cityName));

        public async Task CityTappedCommandFunction(string cityName)
        {
            _preferenceStorage.Set("Latitude", double.MinValue);
            _preferenceStorage.Set("Longitude", double.MinValue);
            _preferenceStorage.Set("City", cityName);
            _preferenceStorage.Set("newQuery", true);
            //更新历史搜索。
            var temp = _preferenceStorage.Get("His1", "北京市");
            _preferenceStorage.Set("His1", cityName);
            _preferenceStorage.Set("His2", temp);
            await _punchNavigationService.NavigateBackAsync(
                ContentNavigationConstant.NewIndexPage, cityName);
        }

        private RelayCommand<object> _specialLocationCommand;

        public RelayCommand<object> SpecialLocationCommand =>
            _specialLocationCommand ??= new RelayCommand<object>(async p =>
                await SpecialLocationCommandFunction(p));

        public async Task
            SpecialLocationCommandFunction(object specialLocation)
        {
            var cityName = specialLocation.ToString();
            if (cityName == _preferenceStorage.Get("CurrentCity", "无"))
            {
                _preferenceStorage.Set("Latitude",
                    _preferenceStorage.Get("currentLocationLatitude",
                        double.MinValue));
                _preferenceStorage.Set("Longitude",
                    _preferenceStorage.Get("currentLocationLongitude",
                        double.MinValue));
                _preferenceStorage.Set("newQuery", true);
                _preferenceStorage.Set("City", cityName);
            }
            else
            {
                _preferenceStorage.Set("Latitude", double.MinValue);
                _preferenceStorage.Set("Longitude", double.MinValue);
                _preferenceStorage.Set("City", cityName);
                _preferenceStorage.Set("newQuery", true);
            }

            await _punchNavigationService.NavigateBackAsync(
                ContentNavigationConstant.NewIndexPage, cityName);
        }
    }
}
